const events = require("events");
const {exec, spawn} = require('child_process');
const fs = require('fs');

const EVENTS = {
    CHANGE:'change',
    FIND_STA:'findStation'
}

const REGEX = {
    MAC_ADDR : /^([a-z\d]{2}\:){5}[a-z\d]{2}/,
    RX_PACKAGES : /^rx_packets=(\d*)/,
    TX_PACKAGES : /^tx_packets=(\d*)/,
    RX_BYTES : /^rx_bytes=(\d*)/,
    TX_BYTES : /^tx_bytes=(\d*)/,
    CONN_TIME: /^connected_time=(\d*)/,
    SIGNAL:/signal=(-*\d*)/,
    LINESPLITE : /[\r\n]/
}

class StationParser extends events.EventEmitter {
    constructor(){
        super();
    }
    parse(string){
        //console.log(string);
        let sta = null;
        string.split(REGEX.LINESPLITE).forEach(line => {
            //console.log("check:",line);
            if(REGEX.MAC_ADDR.test(line)){
                sta = {'MAC':line};
            }
            if(sta == null)
               return;

            let rxresult = REGEX.RX_PACKAGES.exec(line);
            if(rxresult != null){
                sta['rx_packets'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
            rxresult = REGEX.TX_PACKAGES.exec(line);
            if(rxresult != null){
                sta['tx_packets'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
            rxresult = REGEX.RX_BYTES.exec(line);
            if(rxresult != null){
                sta['rx_bytes'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
            rxresult = REGEX.TX_BYTES.exec(line);
            if(rxresult != null){
                sta['tx_bytes'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
            rxresult = REGEX.CONN_TIME.exec(line);
            if(rxresult != null){
                sta['conn_time'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
            rxresult = REGEX.SIGNAL.exec(line);
            if(rxresult != null){
                sta['signal'] = rxresult[1];
                //console.log("check:",rxresult[1]);
            }
        });
        if(sta)
          this.emit(EVENTS.FIND_STA,sta);

    }
}

class HostapdParser extends events.EventEmitter {

    constructor(){
        super();
    }

    runAllSta(){
        const stationParse = new StationParser();
        //抛到上一层事件
        stationParse.on(EVENTS.FIND_STA,(sta)=>{this.emit(EVENTS.FIND_STA,sta)});

        this.run(['all_sta'],{
            onData : (data)=>{
                stationParse.parse(data.toString());
            },
            onClose : (code,data)=>{
                if (code !== 0){
                    console.log('program exit with error. code:${code}');
                }
            },
        })
    }

    run(params,{onData,onError,onClose}){

        //let result = fs.readFileSync('./test.txt',{encoding :'utf8'});
        //onData(result);
        //return;
        const hostapd_cli = spawn('hostapd_cli',params,{detached : false});
        hostapd_cli.stdout.on('data', (data) => {
          onData && onData(data);
        });
        
        hostapd_cli.stderr.on("data",(data)=>{
           onError && onError(data);
        });
        
        hostapd_cli.on("close",(code,signal) =>{
           onClose && onClose(code,signal);
        });
    }    
}

class StationMonitor extends events.EventEmitter{
    constructor(){
        super();
        this.interval = null;
        this.hostapdParser = new HostapdParser();
        this.hostapdParser.on(EVENTS.FIND_STA,(sta)=>{
            this.emit(EVENTS.CHANGE,sta);
        });
    }
    _parseCmd(param){
        param && param.hostapdParser.runAllSta();
    }

    start(){
        this.interval = setInterval(this._parseCmd,1000,this);
    }
    stop(){
        clearInterval(this.interval);
    }
}

module.exports = { StationMonitor, EVENTS};
